using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Net.NetworkInformation;

namespace wicpowerTcpTool
{
    /// <summary>
    /// TCP转发组类，负责管理一对TCP服务器之间的数据转发
    /// </summary>
    public class ForwardGroup
    {
        /// <summary>
        /// 转发组唯一标识
        /// </summary>
        public int Id { get; private set; }

        /// <summary>
        /// 监听端口号
        /// </summary>
        public int Port1 { get; private set; }

        /// <summary>
        /// 转发目标端口号
        /// </summary>
        public int Port2 { get; private set; }

        /// <summary>
        /// 转发组说明备注
        /// </summary>
        public string Remark { get; private set; }
        
        private TcpListener server1;    // 监听服务器
        private TcpListener server2;    // 转发服务器
        private bool isRunning;         // 运行状态标志
        private CancellationTokenSource cancellationToken;  // 取消令牌源

        // 服务器状态变化事件
        public event EventHandler<bool> Server1StatusChanged;
        public event EventHandler<bool> Server2StatusChanged;
        public event EventHandler<bool> Client1Connected;
        public event EventHandler<bool> Client2Connected;
        public event EventHandler DataTransferred;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id">转发组ID</param>
        /// <param name="port1">监听端口</param>
        /// <param name="port2">转发端口</param>
        /// <param name="remark">备注说明</param>
        public ForwardGroup(int id, int port1, int port2, string remark)
        {
            Id = id;
            Port1 = port1;
            Port2 = port2;
            Remark = remark;
            cancellationToken = new CancellationTokenSource();
        }

        /// <summary>
        /// 检查端口是否可用
        /// </summary>
        /// <param name="port">要检查的端口</param>
        /// <returns>(bool isAvailable, string errorMessage)</returns>
        public static (bool isAvailable, string errorMessage) CheckPortAvailable(int port)
        {
            try
            {
                // 检查端口是否在有效范围内
                if (port < 1 || port > 65535)
                {
                    return (false, $"端口 {port} 超出有效范围(1-65535)");
                }

                // 检查端口是否被系统保留
                if (port < 1024)
                {
                    return (false, $"端口 {port} 是系统保留端口");
                }

                // 检查端口是否被占用
                var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
                var tcpListeners = ipGlobalProperties.GetActiveTcpListeners();
                var tcpConnections = ipGlobalProperties.GetActiveTcpConnections();

                if (tcpListeners.Any(l => l.Port == port) || 
                    tcpConnections.Any(c => c.LocalEndPoint.Port == port))
                {
                    return (false, $"端口 {port} 已被占用");
                }

                // 尝试创建测试监听器
                TcpListener testListener = null;
                try
                {
                    testListener = new TcpListener(IPAddress.Loopback, port);
                    testListener.Start();
                    return (true, null);
                }
                finally
                {
                    testListener?.Stop();
                }
            }
            catch (Exception ex)
            {
                return (false, $"端口 {port} 检查失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 启动转发服务前的检查
        /// </summary>
        /// <returns>(bool canStart, string errorMessage)</returns>
        public (bool canStart, string errorMessage) CanStart()
        {
            // 检查端口1
            var (port1Available, port1Error) = CheckPortAvailable(Port1);
            if (!port1Available)
            {
                return (false, port1Error);
            }

            // 检查端口2
            var (port2Available, port2Error) = CheckPortAvailable(Port2);
            if (!port2Available)
            {
                return (false, port2Error);
            }

            return (true, null);
        }

        /// <summary>
        /// 启动转发服务
        /// </summary>
        public async Task Start()
        {
            if (isRunning) return;
            
            var (canStart, errorMessage) = CanStart();
            if (!canStart)
            {
                throw new InvalidOperationException(errorMessage);
            }

            isRunning = true;
            server1 = new TcpListener(IPAddress.Any, Port1);
            server2 = new TcpListener(IPAddress.Any, Port2);

            try
            {
                // 启动两个TCP服务器
                server1.Start();
                Server1StatusChanged?.Invoke(this, true);
                
                server2.Start();
                Server2StatusChanged?.Invoke(this, true);

                // 持续监听连接请求
                while (!cancellationToken.Token.IsCancellationRequested)
                {
                    // 等待客户端1连接
                    var client1 = await server1.AcceptTcpClientAsync();
                    Client1Connected?.Invoke(this, true);

                    // 等待客户端2连接
                    var client2 = await server2.AcceptTcpClientAsync();
                    Client2Connected?.Invoke(this, true);

                    // 启动数据转发
                    _ = ForwardDataAsync(client1, client2);
                }
            }
            catch (Exception)
            {
                Stop();
                throw;
            }
        }

        /// <summary>
        /// 处理数据转发
        /// </summary>
        /// <param name="client1">源客户端</param>
        /// <param name="client2">目标客户端</param>
        private async Task ForwardDataAsync(TcpClient client1, TcpClient client2)
        {
            try
            {
                var stream1 = client1.GetStream();
                var stream2 = client2.GetStream();
                byte[] buffer = new byte[8192];  // 8KB缓冲区

                // 持续转发数据
                while (!cancellationToken.Token.IsCancellationRequested)
                {
                    // 从客户端1读取数据
                    int bytesRead = await stream1.ReadAsync(buffer, 0, buffer.Length);
                    if (bytesRead == 0) break;  // 连接关闭

                    // 发送数据到客户端2
                    await stream2.WriteAsync(buffer, 0, bytesRead);
                    DataTransferred?.Invoke(this, EventArgs.Empty);
                }
            }
            catch (Exception)
            {
                // 处理连接断开等异常
            }
            finally
            {
                // 清理连接
                client1.Close();
                client2.Close();
                Client1Connected?.Invoke(this, false);
                Client2Connected?.Invoke(this, false);
            }
        }

        /// <summary>
        /// 停止转发服务
        /// </summary>
        public void Stop()
        {
            if (!isRunning) return;

            cancellationToken.Cancel();
            server1?.Stop();
            server2?.Stop();
            Server1StatusChanged?.Invoke(this, false);
            Server2StatusChanged?.Invoke(this, false);
            isRunning = false;
        }
    }
} 